package main

//https://www.cnblogs.com/liuqingzheng/p/15996036.html

//Context，翻译为"上下文"，context包定义了Context接口类型
//其接口方法定义了跨API和进程之间的执行最后期限、取消信号和其他请求范围的值
//在并发程序中，由于超时、取消操作或者一些异常情况，往往需要进行抢占操作或者中断后续操作

/*context常用的使用场景：
1、一个请求对应多个goroutine之间的数据交互
2、超时控制
3、上下文控制

context.Context是一个接口，该接口定义了四个需要实现的方法：
type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key interface{}) interface{}
}
Deadline:是获取设置的截止时间的意思，第一个返回值是截止时间，到了这个时间点，Context 会自动发起取消请求；
第二个返回值 ok==false 时表示没有设置截止时间，如果需要取消的话，需要调用取消函数进行取消。

Done:该方法返回一个只读的 chan，类型为 struct{}，我们在 goroutine 中，如果该方法返回的 chan 可以读取
，则意味着parent context已经发起了取消请求，我们通过 Done 方法收到这个信号后，就应该做清理操作，然后退出 goroutine，释放资源。

Err 方法返回取消的错误原因，因为什么 Context 被取消。

Value方法获取该 Context 上绑定的值，是一个键值对，所以要通过一个 Key 才可以获取对应的值，这个值一般是线程安全的
*/

/*context.Background()返回非零的空上下文。它从不被取消，没有值，也没有最后期限。它通常由主函数、初始化和测试使用，
并且作为传入请求的顶级上下文。
context.TODO()返回非零的空上下文。当不清楚要使用哪个上下文或者它还不可用时。应该使用context.TODO()。
本质来讲两者区别不大，其源码实现是一样的，只不过使用场景不同，context.Background()通常由主函数、初始化和测试使用，
是顶级Context；context.TODO()通常用于主协程外的其他协程向下传递，分析工具可识别它在调用栈中传播
*/
